package io.gitee.kotle.android.library.banner.impl.ybanner

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.widget.FrameLayout
import android.widget.LinearLayout.HORIZONTAL
import androidx.fragment.app.Fragment
import androidx.lifecycle.LifecycleOwner
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import io.gitee.kotle.android.iInterface.ILifecycleObserver
import io.gitee.kotle.android.utils.appCompatActivity
import io.gitee.kotle.android.utils.findFragment
import io.gitee.kotle.android.widget.BaseFrameLayout
import java.lang.ref.WeakReference
import kotlin.math.abs

class BannerLayout : BaseFrameLayout, ILifecycleObserver {

    private var lifecycleOwner: LifecycleOwner? = null

    //是否可以滑动
    var isEnableScroll = true

    //滚动时长
    var autoScrollDuration = 1000

    //是否自动滚动
    var canAutoScroll = true
        set(value) {
            field = value
            if (value) {
                start()
            } else {
                stop()
            }
        }

    //自动滚动间隔
    var autoScrollInterval = 3000L

    val viewPager2 by lazy {
        ViewPager2(context).apply {
            layoutParams = LayoutParams(
                FrameLayout.LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT
            )
        }
    }
    internal val rcv by lazy { viewPager2.getChildAt(0) as RecyclerView }

    private val autoTask by lazy { AutoTask(WeakReference(this)) }

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    )

    init {
        addView(viewPager2)
        YScrollSpeedManger.reflectLayoutManager(this)
        val fragment = findFragment<Fragment>()
        if (fragment != null) {
            setLifecycle(fragment)
        } else {
            setLifecycle(appCompatActivity)
        }
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        if (!viewPager2.isUserInputEnabled) {
            return super.dispatchTouchEvent(ev)
        }
        val action = ev.actionMasked
        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_OUTSIDE) {
            start()
        } else if (action == MotionEvent.ACTION_DOWN) {
            stop()
        }
        return super.dispatchTouchEvent(ev)
    }

    private var mStartX = 0f
    private var mStartY = 0f
    private var mIsViewPager2Drag = false
    private val mTouchSlop by lazy { ViewConfiguration.get(context).scaledTouchSlop / 3 }
    override fun onInterceptTouchEvent(event: MotionEvent?): Boolean {
        if (!isEnableScroll) {
            return true
        }
        if (!viewPager2.isUserInputEnabled) {
            return super.onInterceptTouchEvent(event)
        }
        when (event!!.action) {
            MotionEvent.ACTION_DOWN -> {
                mStartX = event.x
                mStartY = event.y
                parent.requestDisallowInterceptTouchEvent(true)
            }
            MotionEvent.ACTION_MOVE -> {
                val endX = event.x
                val endY = event.y
                val distanceX: Float = abs(endX - mStartX)
                val distanceY: Float = abs(endY - mStartY)
                mIsViewPager2Drag = if (viewPager2.orientation == HORIZONTAL) {
                    distanceX > mTouchSlop && distanceX > distanceY
                } else {
                    distanceY > mTouchSlop && distanceY > distanceX
                }
                parent.requestDisallowInterceptTouchEvent(mIsViewPager2Drag)
            }
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> parent.requestDisallowInterceptTouchEvent(
                false
            )
        }
        return super.onInterceptTouchEvent(event)
    }


    /**
     * 是否消费事件
     * 消费:事件就结束
     * 不消费:往父控件传
     */
    override fun onTouchEvent(ev: MotionEvent?): Boolean { //return false;// 可行,不消费,传给父控件
        //return true;// 可行,消费,拦截事件
        //super.onTouchEvent(ev); //不行,
        //虽然onInterceptTouchEvent中拦截了,
        //但是如果viewpage里面子控件不是viewgroup,还是会调用这个方法.
        return if (isEnableScroll) {
            super.onTouchEvent(ev)
        } else {
            true // 可行,消费,拦截事件
        }
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        start()
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        stop()
    }

    override fun onStart() {
        super.onStart()
        start()
    }

    override fun onStop() {
        super.onStop()
        stop()
    }

    override fun onVisibilityChanged(changedView: View, visibility: Int) {
        super.onVisibilityChanged(changedView, visibility)
        if (changedView == this) {
            if (visibility == View.VISIBLE) {
                start()
            } else {
                stop()
            }
        }
    }


    private open class AutoTask(private val yBanner: WeakReference<BannerLayout>) : Runnable {
        override fun run() {
            yBanner.get()?.let {
                val adapter = it.viewPager2.adapter
                if (adapter != null) {
                    val next = it.viewPager2.currentItem + 1
                    if (next < adapter.itemCount) {
                        it.viewPager2.currentItem = next
                        it.postDelayed(it.autoTask, it.autoScrollInterval + it.autoScrollDuration)
                    }
                }

            }
        }
    }

    /*****************************支持对外调用****************************/
    fun start() {
        if (canAutoScroll) {
            this.let {
                stop()
                it.postDelayed(it.autoTask, it.autoScrollInterval + it.autoScrollDuration)
            }
        }
    }

    fun stop() {
        removeCallbacks(autoTask)
    }

    override fun onDestroy() {
        lifecycleOwner = null
        super.onDestroy()
    }

    fun setLifecycle(owner: LifecycleOwner?) {
        lifecycleOwner = if (owner == null) {
            lifecycleOwner?.lifecycle?.removeObserver(this)
            null
        } else {
            lifecycleOwner?.lifecycle?.removeObserver(this)
            owner.lifecycle.addObserver(this)
            owner
        }
    }
}